package com.mzkj.wanjulaile.mobile.api.modules.order.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.collect.Maps;
import com.mzkj.common.data.StatusCode;
import com.mzkj.common.utils.Collections3;
import com.mzkj.common.utils.DateUtils;
import com.mzkj.common.utils.StringUtils;
import com.mzkj.wanjulaile.mobile.api.common.controller.BaseController;
import com.mzkj.wanjulaile.mobile.api.common.entity.ResultEntity;
import com.mzkj.wanjulaile.mobile.api.modules.account.entity.Account;
import com.mzkj.wanjulaile.mobile.api.modules.account.service.AccountService;
import com.mzkj.wanjulaile.mobile.api.modules.address.entity.Address;
import com.mzkj.wanjulaile.mobile.api.modules.address.service.AddressService;
import com.mzkj.wanjulaile.mobile.api.modules.order.constant.Constant;
import com.mzkj.wanjulaile.mobile.api.modules.order.entity.Order;
import com.mzkj.wanjulaile.mobile.api.modules.order.service.OrderService;
import com.mzkj.wanjulaile.mobile.api.modules.order.service.OrderToyService;
import com.mzkj.wanjulaile.mobile.api.modules.order.service.WXOrderService;
import com.mzkj.wanjulaile.mobile.api.modules.toy.entity.Image;
import com.mzkj.wanjulaile.mobile.api.modules.toy.entity.Toy;
import com.mzkj.wanjulaile.mobile.api.modules.toy.service.ImageService;
import com.mzkj.wanjulaile.mobile.api.modules.toy.service.ToyService;
import com.mzkj.wanjulaile.mobile.api.modules.weChat.entity.NotifyReturnData;
import com.mzkj.wanjulaile.mobile.api.modules.weChat.service.NotifyReturnService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.*;


@Controller
@RequestMapping(value = "auth/order")
public class OrderAuthController extends BaseController {
    @Autowired
    private AccountService accountService;
    @Autowired
    private ToyService toyService;
    @Autowired
    private AddressService addressService;
    @Autowired
    private OrderToyService orderToyService;
    @Autowired
    private ImageService imageService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private WXOrderService wxOrderService;
    @Autowired
    private NotifyReturnService notifyReturnService;
    @Value("${shipFee}")
    private Integer shipFee;

    /**
     * 购物车到订单确认页后显示的数据
     *
     * @param toyIds    购买的玩具id数组
     * @param addressId 地址id
     * @param request   accessToken
     * @return
     */
    @RequestMapping("/getData")
    @ResponseBody
    public ResultEntity<Map<String, Object>> index(String[] toyIds, String addressId, HttpServletRequest request) {
        ResultEntity<Map<String, Object>> result = new ResultEntity<>();
        String accountId = (String) request.getAttribute("accountId");
        Map<String, Object> data = new HashMap<>();
        try {
            Address address = null;
            if (toyIds == null || toyIds.length <= 0) {
                return new ResultEntity<>(StatusCode.SC4001);
            }

            if(!StringUtils.isEmpty(addressId)){
                address=addressService.get(addressId);
            }else{
                List<Address> addressesList = addressService.getListByAccountId(accountId);
                if (!Collections3.isEmpty(addressesList)) {
                    address = addressService.getDefaultAddress(accountId);
                    if (address == null) {
                        address = addressesList.get(0);
                    }
                }
            }
            List<Toy> toyList = toyService.getByIds(Arrays.asList(toyIds));
            Account account = accountService.get2(accountId);
            //查找上次使用中的玩具
            Order lastOrder = orderService.getLastOrderByAccountId(accountId);
            if (lastOrder != null) {
                List<Toy> oldToyList = orderToyService.getToyListToyByOrderId(lastOrder.getId());
                if (!Collections3.isEmpty(oldToyList)) {
                    for (Toy toy : oldToyList) {
                        setImage(toy);
                    }
                    data.put("oldToyList", oldToyList);
                }
            } else {
                data.put("oldToyList", new ArrayList<Toy>());
            }
            data.put("appointDateList", getAppointDateList(account));
            data.put("toyList", toyList);
//            data.put("account", account);
            data.put("address", address);
            data.put("shipFee", shipFee);
            result.setStatusCode(StatusCode.SC0.getValue());
            result.setData(data);
            result.setMsg(StatusCode.SC0.getDesc());
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatusCode(StatusCode.SC4002.getValue());
            result.setMsg(StatusCode.SC4002.getDesc());
        }
        return result;
    }

    /**
     * 查找上次下单的玩具
     *
     * @param request accessToken
     * @return
     */
    @RequestMapping("/getOldToyList")
    @ResponseBody
    public ResultEntity<List<Toy>> getOldToyList(HttpServletRequest request) {
        ResultEntity<List<Toy>> result = new ResultEntity<List<Toy>>();
        String accountId = (String) request.getAttribute("accountId");
        try {
            //查找上次使用中的玩具
            Order lastOrder = orderService.getLastOrderByAccountId(accountId);
            if (lastOrder != null) {
                //List<Toy> oldToyList = orderToyService.getRentToyByAccountId(accountId);
                List<Toy> oldToyList = orderToyService.getToyListToyByOrderId(lastOrder.getId());
                if (!Collections3.isEmpty(oldToyList)) {
                    for (Toy toy : oldToyList) {
                        setImage(toy);
                    }
                    result.setData(oldToyList);
                    result.setStatusCode(StatusCode.SC0.getValue());
                    result.setMsg(StatusCode.SC0.getDesc());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatusCode(StatusCode.SC4002.getValue());
            result.setMsg(StatusCode.SC4002.getDesc());
        }
        return result;
    }

    /**
     * 订单提交
     *
     * @param toyIds          购买玩具id拼接字符串
     * @param addressId       地址id
     * @param appointDate     用户预约配送时间
     * @param reToyIds        退还玩具id 拼接字符串
     * @param oldReToyIds     续租玩具id 拼接字符串(无用)
     * @param accountCouponId 用户的优惠券id
     * @param request         accessToken
     * @return
     */
    @RequestMapping(value = "submit",method = RequestMethod.POST)
    @ResponseBody
    public ResultEntity<Order> orderSubmit(String toyIds, String addressId, String appointDate, String reToyIds, String oldReToyIds, String accountCouponId, HttpServletRequest request) {
        ResultEntity<Order> result = new ResultEntity<Order>();
        String accountId = (String) request.getAttribute("accountId");
        try {
            Account account = accountService.get2(accountId);
            if (account.getVipType().equals(0)) {
                //不是vip
                return new ResultEntity<>(StatusCode.SC40000);
            }
            if (StringUtils.isEmpty(appointDate)) {
                return new ResultEntity<>(StatusCode.SC400301);
            }
            if (StringUtils.isEmpty(addressId)) {
                return new ResultEntity<>(StatusCode.SC40015);
            } else {
                List<Address> addressList = addressService.getListByAccountId(accountId);
                Map<String, Address> map = Maps.newHashMap();
                if (!Collections3.isEmpty(addressList)) {
                    for (Address address : addressList) {
                        map.put(address.getId(), address);
                    }
                    if (!map.containsKey(addressId)) {
                        return new ResultEntity<>(StatusCode.SC40015);
                    }
                }
            }
            //四点前校验
            //if (validateShipDate(appointDate, result)) {
            //    return result;
            //}
            //本次想租的玩具
            List<String> toyIdList = new ArrayList<String>();
            if (!StringUtils.isEmpty(toyIds)) {
                String[] toyIdArr=toyIds.split(",");
                for(String id:toyIdArr){
                    toyIdList.add(id);
                }
            } else {
                return new ResultEntity<>(StatusCode.SC4001);
            }
            //选择退还的玩具
            List<String> reToyIdList = new ArrayList<String>();
            if (!StringUtils.isEmpty(reToyIds)) {
                String[] retoyIdArr=reToyIds.split(",");
                for(String id:retoyIdArr){
                    reToyIdList.add(id);
                }
            }
            //续租玩具
            List<String> oldReToyIdList = new ArrayList<String>();
            if (!StringUtils.isEmpty(oldReToyIds)) {
                String[] oldretoyIdArr=oldReToyIds.split(",");
                for(String id:oldretoyIdArr){
                    oldReToyIdList.add(id);
                }
            }
            //历史玩具
            List<String> oldToyIdList = new ArrayList<String>();
            //查找上次使用中的玩具
            Order lastOrder1 = orderService.getLastOrderByAccountId(accountId);
            if (lastOrder1 != null) {
                List<Toy> oldToyList = orderToyService.getToyListToyByOrderId(lastOrder1.getId());
                Map<String, Toy> map = Maps.newHashMap();
                if (!Collections3.isEmpty(oldToyList)) {
                    for (Toy toy : oldToyList) {
                        oldToyIdList.add(toy.getId());
                        map.put(toy.getId(), toy);
                    }
                }
                if (!Collections3.isEmpty(oldToyIdList)) {
                    if (!Collections3.isEmpty(reToyIdList)) {
                        //退还的玩具是否合法
                        for (String id : reToyIdList) {
                            if (!map.containsKey(id)) {
                                return new ResultEntity<>(StatusCode.SC40014);
                            }
                        }
                        for (String id : reToyIdList) {
                            oldToyIdList.remove(id);
                        }
                    }
                    //添加续租玩具
                    for (String id : oldToyIdList) {
                        oldReToyIdList.add(id);
                    }
                }
            }
            if (validate(toyIdList, reToyIdList)) {
                return new ResultEntity<>(StatusCode.SC40001);
            }
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("toyIdList", toyIdList);
            params.put("accountId", account.getId());
            params.put("shipFee", shipFee);
            params.put("appointDate", appointDate);
            params.put("addressId", addressId);
            params.put("reToyIdList", reToyIdList);
            params.put("oldReToyIdList", oldReToyIdList);
            params.put("accountCouponId", accountCouponId);
            //上一次订单
            Order lastOrder = orderService.getLastOrderByAccountId2(account.getId());
            if (lastOrder != null && lastOrder.getCurVipType().equals(4) && !account.getVipType().equals(4)) {
                if (lastOrder.getPayStatus().equals(Constant.PAY_STATUS_NOT_PAID_)) {
                    return new ResultEntity<>(StatusCode.SC400501);
                }
                if (lastOrder.getStatus().equals(Constant.ORDER_CREATE)) {
                    return new ResultEntity<>(StatusCode.SC400502);
                } else if (lastOrder.getStatus().equals(Constant.ORDER_CONFIRM) || lastOrder.getStatus().equals(Constant.ORDER_SENDING)) {
                    return new ResultEntity<>(StatusCode.SC40006);
                }
            } else {
                //校验租赁周期内
                if (wxOrderService.validateLimitDate(account.getId(), result, appointDate)) {
                    return result;
                }
            }
            //合并
            List<String> newIdsList = new ArrayList<String>();
            Map<String, Integer> buyToy = setNewIdsList(toyIdList, oldReToyIdList, newIdsList);
            result = wxOrderService.toSaveOrder(params,buyToy,result);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatusCode(StatusCode.SC40002.getValue());
            result.setMsg(StatusCode.SC40002.getDesc());
        }
        return result;
    }

    private boolean validateShipDate(String appointDate, ResultEntity<Order> result) {
        appointDate = appointDate.substring(0, appointDate.indexOf('('));
        Date date = DateUtils.parseDate(appointDate);
        Long limit = DateUtils.getDistanceOfTwoDate(new Date(), date);
        System.out.println(limit);
        System.out.println(DateUtils.getPastHour());
        if (limit == 0 && DateUtils.getPastHour() > 16) {
            result.setStatusCode(StatusCode.SC400302.getValue());
            result.setMsg(StatusCode.SC400302.getDesc());
            return true;
        }
        if (limit < 0 || limit > 7) {
            result.setStatusCode(StatusCode.SC400303.getValue());
            result.setMsg(StatusCode.SC400303.getDesc());
            return true;
        }

        return false;
    }


    private Map<String, Integer> setNewIdsList(List<String> toyIdList, List<String> oldReToyIdList, List<String> newIdsList) {
        Map<String, Integer> resultIds = new HashMap<String, Integer>();
        if (!Collections3.isEmpty(toyIdList)) {
            for (String id : toyIdList) {
                newIdsList.add(id);
            }
        }
        // TODO
        if (!Collections3.isEmpty(oldReToyIdList)) {
            for (String id : oldReToyIdList) {
                newIdsList.add(id);
            }
        }
        if (!Collections3.isEmpty(newIdsList)) {
            for (String id : newIdsList) {
                if (resultIds.containsKey(id)) {
                    resultIds.put(id, resultIds.get(id) + 1);
                } else {
                    resultIds.put(id, 1);
                }
            }
        }
        return resultIds;
    }

    //再次租的玩具和退还玩具重复
    private boolean validate(List<String> toyIdList, List<String> reToyIdList) {
        if (!Collections3.isEmpty(reToyIdList)) {
            for (String id : reToyIdList) {
                if (toyIdList.contains(id)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 获取订单列表
     *
     * @param request accessToken
     * @return
     */
    @ResponseBody
    @RequestMapping("/getOrderList")
    public ResultEntity<String> getData(HttpServletRequest request) {
        ResultEntity<String> result = new ResultEntity<>();
        String accountId = (String) request.getAttribute("accountId");
        try {
            List<Order> orderList = orderService.findListByAccountId(accountId);
            result.setStatusCode(StatusCode.SC0.getValue());
            result.setMsg(StatusCode.SC0.getDesc());
            result.setData(JSON.toJSONString(orderList, SerializerFeature.DisableCircularReferenceDetect));
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatusCode(StatusCode.SC4002.getValue());
            result.setMsg(StatusCode.SC4002.getDesc());
        }
        return result;
    }

    /**
     * 根据id获取订单详情
     *
     * @param id 订单id
     * @return
     */
    @ResponseBody
    @RequestMapping("/get")
    public ResultEntity<Order> getById(String id) {
        ResultEntity<Order> result = new ResultEntity<Order>();
        try {
            Order order = orderService.get(id);
            result.setStatusCode(StatusCode.SC0.getValue());
            result.setMsg(StatusCode.SC0.getDesc());
            result.setData(order);
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatusCode(StatusCode.SC4002.getValue());
            result.setMsg(StatusCode.SC4002.getDesc());
        }
        return result;
    }

    /**
     * 订单取消
     *
     * @param id 订单id
     * @return
     */
    @ResponseBody
    @RequestMapping("/cancel")
    public ResultEntity<Order> cancel(String id) {
        ResultEntity<Order> result = new ResultEntity<>();
        Order order = new Order(id);
        try {
            Order temp = orderService.get(id);
            if (temp.getStatus() > 1) {
                return new ResultEntity<>(StatusCode.SC400104);
            }
            order.setStatus(Constant.ORDER_CANCEL);
            orderService.updateStatus(order);
            temp.setStatus(Constant.ORDER_CANCEL);
            result.setData(temp);
            result.setStatusCode(StatusCode.SC0.getValue());
            result.setMsg(StatusCode.SC0.getDesc());
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatusCode(StatusCode.SC5000.getValue());
            result.setMsg(StatusCode.SC5000.getDesc());
        }
        return result;
    }


    private void setImage(Toy toy) {
        Image image = new Image();
        image.setToy(toy);
        toy.setImages(imageService.getListByToyId(image));
    }

    public List<String> getAppointDateList(Account account) {
        List<String> appointDateList = new ArrayList<String>();
        if (DateUtils.getPastHour() < 17) {
            forAppointDateList(appointDateList, 1, 7,account);
        } else if (DateUtils.getPastHour() >= 17) {
            forAppointDateList(appointDateList, 2, 6,account);
        }

        return appointDateList;
    }

    private void forAppointDateList(List<String> appointDateList, int k, int limit, Account account) {
        for (int i = k; appointDateList.size() < limit; i++) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DATE, +i);
            Date time = calendar.getTime();
            if (null != account.getVipEnd() && DateUtils.compareStringDate(account.getVipEnd(),DateUtils.formatDate(time))<=0){
                break;
            }
            appointDateList.add(DateUtils.formatDate(time) + "(" + DateUtils.getWeekOfDate(time) + ")");
        }
    }


}